package com.polytech.tablespaceResolver.Resolver;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import com.polytech.tablespaceResolver.ORMUtils.DBCredentials;
import com.polytech.tablespaceResolver.ORMUtils.ORMUtils;
import com.polytech.tablespaceResolver.Parsers.FromClauseParser;
import com.polytech.tablespaceResolver.configuration.PropertyLoader;

public class TablespaceResolver {
	ORMUtils utils;
	HashMap<String, List<String>> dbStructure;
	
	public void initialize()
	{
		DBCredentials credentials = PropertyLoader.getInstance().loadCredentials();
		
		utils = ORMUtils.getInstance();		
		utils.connect(credentials);
		
		dbStructure = (HashMap<String, List<String>>) 
								utils.getDBStructure(credentials.getSchema());
	}
	
	public void doResolving()
	{
		List<String> queries = utils.getDBlog();
		List<String> resolvedQueries = new ArrayList<String>();
		
		for(String query : queries)
		{
			resolvedQueries.add(resolveQuery(query));
		}
		
		saveResults(resolvedQueries);
	}
	
	private String resolveQuery(String query)
	{
		Map<String,String> tables = FromClauseParser.parseFromClause(query);
		
		for(Entry<String,String> entry : tables.entrySet())
		{
			List<String> columns = dbStructure.get(entry.getKey());
			if(columns != null)
				query = updateQuery(query, entry.getKey(), entry.getValue(), columns);
		}
		
		return query;
	}
	
	private String updateQuery(String query, String table, String alias, List<String> columns)
	{
		query = query.replaceAll(" +", " ").replaceAll("\n|\r", "");
		
		for(String column : columns)
		{
			//" + table + "
			Pattern colPattern = Pattern.compile("( " + alias.trim() + "|" + table.trim() + "\\.)?(" + column + ")");
			Matcher colMatcher = colPattern.matcher(query);
			query = colMatcher.replaceAll(" " + table.trim()+"." + column);
			
			while(colMatcher.find())
			{
				if(colMatcher.group(1) == null || !colMatcher.group(1).trim().equals(table))
				{
					
				}
					query = colMatcher.replaceFirst(" " + table.trim()+".$3");
				
			}
			
			
		}

		return query;
	}
	
	private void saveResults(List<String> resolvedQueries)
	{
		utils.storeResults(resolvedQueries);
	}
	
	public void emptyResources()
	{
		utils.disconnect();
	}
	
	public void parse()
	{
		List<String> queries = utils.getDBlog();
		List<String> resolvedQueries = new ArrayList<String>();
		utils.init();
		
		for(String query : queries)
		{
			Map<String, List<String>> result = parseQuery(query);
			utils.stroreParsedTables(result);
		}
		
		utils.flush();
	}
	
	private Map<String, List<String>> parseQuery(String query)
	{
		Set<String> tables = FromClauseParser.parseFromClause(query);
		Map<String, List<String>> result = new HashMap<String, List<String>>();
		
		for(String entry : tables)
		{
			List<String> columns = dbStructure.get(entry);
			List<String> existingColumns = new ArrayList<String>();
			
			if(columns != null)
			{
				query = query.replaceAll(" +", " ").replaceAll("\n|\r", "");
				for(String column : columns)	
				{
					if(query.contains(column))
					{
						existingColumns.add(column);
					}
				}
				result.put(entry, existingColumns);
			}			
		}
		
		return result;
	}
}
